package com.comleader.utils;

import com.alibaba.fastjson.JSONObject;
import com.comleader.entity.Point;
import com.graphhopper.util.shapes.GHPoint;

import java.util.ArrayList;
import java.util.List;

import static com.vividsolutions.jts.geom.CoordinateSequence.M;

public class CorrectionUtils {
//    /**
//     * 获得合法轨迹的list起止下标
//     *计真两点距离的工具类（LocationUtils)自行百度
//     *实体中用到的涫息就是经纬度和时间，我这里时间用的是毫秒的时间戥
//    */
//    private String getSafeIndex(List<Point> gpsList) {
//        int start = 0;//设置起终点
//        int end =0;
//        List<String> indexList = new ArrayList<>();
//        Point dangerBefore = null;
//        for (int i = 1; i < gpsList.size(); i++) {
//            Point dangerVo = gpsList.get(i);
//            if (dangerBefore==null){
//                dangerBefore=gpsList.get(i-1);
//            }
//            //取得两坐标点之间距离
//            double distance = MapUtil.getDistance(dangerVo, dangerBefore);
//            long time = Math.abs(dangerVo.getGpsts() - dangerBefore.getGpsts());
//            //求得时速
//            double speed =(double)(distance/1000/1000)/((double)time % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
//            if (speed > 5) { //判断时速
//                if (end > start) {
//                    indexList.add(end +"-"+start);
//                }
//                start = i;
//            }
//            end = i;
//            dangerBefore = dangerVo;
//        }
//        if (end > start) {
//                indexList.add(end +"-"+ start);
//        }
//        int maxIndex =0;
//        int max =0;
//        for (int i = 0; i < indexList.size() ; i-M-) {
//                int tnpEnd = Integer.valueOf(indexList.get(i).split("-")[0]);
//                int tnpStart = Integer.valueOf(indexList.get(i).split("-")[1]);
//                if (tnpEnd - tnpStart > max) {
//                    max = tnpEnd - tnpStart;
//                    maxIndex = i;
//                }
//        }
//        return indexList.get(maxIndex);
//    }
//    private void removeErrorPoint (List<Point> gpsList) {
//        String safeIndex = getSafeIndex(gpsList);
//        int startIndex = Integer.valueOf(safeIndex.split("-")[1]);
//        int endIndex = Integer.valueOf(safeIndex.split("-")[0]);
//        if (startIndex == 0 && endIndex == gpsList.size() - 1) {
//            return;
//        }
//        List<String> deleteList = new ArrayList<>();
//        Point safeVo = gpsList.get(startIndex);
//        for (int i = startIndex - 1; i > -1; i--) {
//            Point dangerVo = gpsList.get(i);
//            double distance = MapUtil.getDistance(dangerVo, safeVo);
//            long time = Math.abs(dangerVo.getGpsts() - safeVo.getGpsts());
//            double speed = (double) (distance/1000/ 1000) / ((double) time % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
//            if (speed > 5) {
//                deleteList.add(dangerVo.getId());
//            } else {
//                safeVo = dangerVo;
//            }
//        }
//        safeVo = gpsList.get(endIndex);
//        for (int i = endIndex + 1; i < gpsList.size(); i++) {
//            Point dangerVo = gpsList.get(i);
//            double distance = MapUtil.getDistance(dangerVo, safeVo);
//            long time = Math.abs(dangerVo.getGpsts() - safeVo.getGpsts());
//            double speed = (double) (distance/1000/ 1000) / ((double) time % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
//            if (speed > 5) {
//                //加入异常点集合
//                deleteList.add(dangerVo.getId());
//            } else {
//                safeVo = dangerVo;
//            }
//        }
//        //异常点处理
//        if (!deleteList.isEmpty()) {
//            System.out.println(deleteList);
//        }
//    }
    /** 地球半径（千米）. */
    private static double EARTH_RADIUS = 6378.137;
    /** PI. */
    private static double PI = Math.PI;
    /**
     * 计算弧度.
     * @param d 角度
     * @return 弧度
     */
    public static double rad(double d) {
        return d * PI / 180.0;
    }

    /**
     * 计算两点距离（千米）.
     * @param lat1 第一点纬度
     * @param lng1 第一点经度
     * @param lat2 第二点纬度
     * @param lng2 第二点经度
     * @return 距离（千米）
     */
    public static double calcDistanceByKm(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2),2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10000;
        return s;
    }

    /**
     * 计算两点距离（米）.
     * @param lat1 第一点纬度
     * @param lng1 第一点经度
     * @param lat2 第二点纬度
     * @param lng2 第二点经度
     * @return 距离（米）
     */
    public static double calcDistanceByM(double lat1, double lng1, double lat2, double lng2) {
        return calcDistanceByKm(lat1, lng1, lat2, lng2) * 1000;
    }
    /**
     * 轨迹降噪.
     * @param locs 轨迹
     * <pre>
     *     [
     *         {
     *             LocTime:定位记录时间,
     *             LAT:纬度,
     *             LON:经度,
     *             StayTime:停留时间
     *         },
     *         ... ...
     *     ]
     * </pre>
     * @param speedThreshold 去噪速度阈值
     * @return 去噪后的轨迹
     * <pre>
     *     [
     *         {
     *             LocTime:定位记录时间,
     *             LAT:纬度,
     *             LON:经度,
     *             StayTime:停留时间
     *         },
     *         ... ...
     *     ]
     * </pre>
     */
//    public static List<JSONObject> denoise(List<JSONObject> locs, Double speedThreshold) {
//        // 记录点小于5个则直接返回
//        if (null == locs || 5 >= locs.size() || null == speedThreshold) {
//            return locs;
//        }
//        // 确定首点
//        int firstIdx = -1;
//        double tmpDistance1 = 0;
//        long tmpIntervalTime1 = 0;
//        double tmpDistance2 = 0;
//        long tmpIntervalTime2 = 0;
//        // 连续三个点的速度均正常的情况，此三点第一个点为首点
//        for (int i = 0; i < locs.size() - 2; i++) {
//            //第一个点到第二个点的距离（单位为：m）
//            tmpDistance1 = calcDistanceByM(locs.get(i).getDoubleValue(DeviceApiConstants.REQ_LAT),
//                    locs.get(i).getDoubleValue(DeviceApiConstants.REQ_LON),
//                    locs.get(i + 1).getDoubleValue(DeviceApiConstants.REQ_LAT),
//                    locs.get(i + 1).getDoubleValue(DeviceApiConstants.REQ_LON));
//            //第一个点到第二个点间隔时间
//            tmpIntervalTime1 = (locs.get(i + 1).getLongValue(DeviceApiConstants.KEY_LOC_TIME) - locs.get(i).getLongValue(DeviceApiConstants.KEY_LOC_TIME)) * 1000;
//            //第二个点到第三个点的距离（单位为：m）
//            tmpDistance2 = calcDistanceByM(locs.get(i + 1).getDoubleValue(DeviceApiConstants.REQ_LAT),
//                    locs.get(i + 1).getDoubleValue(DeviceApiConstants.REQ_LON),
//                    locs.get(i + 2).getDoubleValue(DeviceApiConstants.REQ_LAT),
//                    locs.get(i + 2).getDoubleValue(DeviceApiConstants.REQ_LON));
//            //第二个点到第三个点间隔时间
//            tmpIntervalTime2 = (locs.get(i + 2).getLongValue(DeviceApiConstants.KEY_LOC_TIME) - locs.get(i + 1).getLongValue(DeviceApiConstants.KEY_LOC_TIME)) * 1000;
//            //去噪速度阈值和点与点之间速度对比
//            if (speedThreshold >= (tmpDistance1 / tmpIntervalTime1)
//                    && speedThreshold >= (tmpDistance2 / tmpIntervalTime2)) {
//                firstIdx = i;
//                break;
//            }
//        }
//        // 如果到最后也没有找到首点，则直接返回全部点
//        if (-1 == firstIdx) {
//            return locs;
//        }
//        // 从首点开始对其后续点进行去噪
//        List<JSONObject> usableLocs = new ArrayList<JSONObject>();
//        for (int i = firstIdx; i < locs.size(); i++) {
//            if (i == firstIdx) {
//                usableLocs.add(locs.get(i));
//            } else {
//                tmpDistance1 = calcDistanceByM(locs.get(i).getDoubleValue(DeviceApiConstants.REQ_LAT),
//                        locs.get(i).getDoubleValue(DeviceApiConstants.REQ_LON),
//                        locs.get(i - 1).getDoubleValue(DeviceApiConstants.REQ_LAT),
//                        locs.get(i - 1).getDoubleValue(DeviceApiConstants.REQ_LON));
//                tmpIntervalTime1 = (locs.get(i).getLongValue(DeviceApiConstants.KEY_LOC_TIME) - locs.get(i - 1).getLongValue(DeviceApiConstants.KEY_LOC_TIME)) * 1000;
//                if (speedThreshold >= (tmpDistance1 / tmpIntervalTime1)) {
//                    usableLocs.add(locs.get(i));
//                }
//            }
//        }
//        return usableLocs;
//    }
}